package cn.zaier.javafx.controlle;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.exceptions.UtilException;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.extra.spring.SpringUtil;
import cn.zaier.javafx.Constants;
import de.felixroske.jfxsupport.FXMLController;
import javafx.application.Platform;
import javafx.concurrent.Worker;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.CheckBox;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.util.Duration;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;

import java.io.*;
import java.lang.reflect.Field;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Properties;
import java.util.concurrent.atomic.AtomicLong;

@Component
public class InitSceneViewControlle {

    public   static AtomicLong count = new AtomicLong(0);
    private  ClearScheduledService clearScheduledService;

    public static volatile boolean isRun=false;
    @FXML
    private Button confirmbtn;

    @FXML
    private TextField fileTtype;

    @FXML
    private TextArea dirpath;  //  文件目录

    @FXML
    private TextField timeIntervel;//

    @FXML
    private TextField fileupdatetimebefore;

    @FXML
    private TextArea  consoleprint;// 控制台

    @FXML
    private CheckBox checkwritelogfile;

    @FXML
    void confirm(ActionEvent event){
        if (StringUtils.isBlank(dirpath.getText())){
            confirmbtn.setText("请先设置目录");
            return;
        }
        if (isRun){
            confirmbtn.setText("重新执行");
            confirmbtn.setUserData("cancel");
            clearScheduledService.cancel();
            isRun=false;
        }else{
            if (clearScheduledService != null && clearScheduledService.getState() == Worker.State.RUNNING){
                clearScheduledService.cancel();
            }
            threadScheduleTask();
            isRun=true;
            confirmbtn.setUserData("run");
            confirmbtn.setText("暂停");
        }
    }

    private void threadScheduleTask() {
        if (StringUtils.isBlank(dirpath.getText())){
            return;
        }
        if (StringUtils.isBlank(timeIntervel.getText())){
            timeIntervel.setText("30");
        }
        HashMap<String, Object> extArgs= new HashMap<String, Object>();
        if (StringUtils.isNotBlank(fileupdatetimebefore.getText())){
            extArgs.put(Constants.FILE_UPDATE_TIME_BEFORE,fileupdatetimebefore.getText()); // 文件最后修改时间大于多少分钟
        }
        clearScheduledService= new ClearScheduledService(dirpath.getText(), fileTtype.getText(), Long.parseLong(timeIntervel.getText()), extArgs);
        clearScheduledService.setPeriod(Duration.seconds(Double.valueOf(timeIntervel.getText()))); //  延迟多久再次执行
        clearScheduledService.start();

    }


    /**
     * 改变了目录
     */
    @FXML
    void changdir(){
        printLog("修改","改变了目录");
        reset();
    }

    private void reset() {
        if (clearScheduledService == null )return;
        clearScheduledService.cancel();
        threadScheduleTask();
    }


    /**
     * 改变了时间
     */
    @FXML
    void changtime(){
        printLog("修改","执行间隔时间");
        reset();
    }


    @FXML
    void changfileupdatetime() {
        printLog("修改","文件最后修改时间");
        reset();
    }



    @FXML
    void changefiletype(){
        printLog("修改","文件类型");
        reset();
    }


    /**
     * 初始化配置
     */
    public void initVal(Class controllerClass,String methodName){
        if (Constants.CONF_FILE.exists()){
            FileReader br=null;
            try {
                br = new FileReader(Constants.CONF_FILE);
                Properties properties = new Properties();
                properties.load(br);
                Field[] fields = this.getClass().getDeclaredFields();
                for (Field field : fields) {
                    field.setAccessible(true);
                    FXML annotation = field.getAnnotation(FXML.class);
                    if (annotation != null){
                        Object bean = SpringUtil.getBean(controllerClass);
                        Object fieldValue = ReflectUtil.getFieldValue(bean, field);
                        printLog("历史配置",methodName+""+properties.getProperty(field.getName()));
                        ReflectUtil.invoke(fieldValue, methodName,properties.getProperty(field.getName()));
                    }
                }
            } catch (IOException e) {
                throw new RuntimeException(e);
            }finally {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }

    public void saveConf(Class controllerClass,String methodName,String... args){
        BufferedWriter bw=null;
        if (Constants.CONF_FILE.exists()){
            Constants.CONF_FILE.delete();
        }
        Properties properties = new Properties();
        try {
            bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(Constants.CONF_FILE)));
            Field[] fields = this.getClass().getDeclaredFields();
            for (Field field : fields) {
                field.setAccessible(true);
                FXML annotation = field.getAnnotation(FXML.class);
                if (annotation != null){
                    Object bean = SpringUtil.getBean(controllerClass);
                    try {
                        Object objectFiled = ReflectUtil.getFieldValue(bean, field);
                        Object value = ReflectUtil.invoke(objectFiled, methodName,args);
                        if (null !=value && !value.equals("")){
                            properties.put(field.getName(),value);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
            properties.store(bw, String.valueOf(StandardCharsets.UTF_8)); // store 方法
        } catch (IOException e) {
            throw new RuntimeException(e);
        }finally {
            try {
                bw.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }


    /**
     * @param title
     * @param msg
     */
    public synchronized void printLog(String title, String msg) {
        String log = DateUtil.now() + "   " + title + ":   " + msg + "\n";
        if (checkwritelogfile!=null && checkwritelogfile.isSelected()){
            BufferedWriter bufferedWriter=null;
            try {
                bufferedWriter = new BufferedWriter(new OutputStreamWriter(
                        new FileOutputStream(new File(Constants.CLASS_PATH + File.separator + Constants.CLEAR_FILE_NAME  +DateUtil.today()+ ".log"), true)));
                bufferedWriter.append(log);
                bufferedWriter.newLine();
                bufferedWriter.flush();
            } catch (IOException e) {
                e.printStackTrace();
            }finally {
                try {
                    bufferedWriter.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
        //# BUG 考虑是否有并发的问题
        Platform.runLater(()-> {
            if (consoleprint!=null){
                consoleprint.appendText(log);
            }
        });
    }
}
